/*********************************************************************************************************************
 * COPYRIGHT NOTICE
 * Copyright (c) 2017,逐飞科技
 * All rights reserved.
 * 技术讨论QQ群：179029047
 *
 * 以下所有内容版权均属逐飞科技所有，未经允许不得用于商业用途，
 * 欢迎各位使用并传播本程序，修改内容时必须保留逐飞科技的版权声明。
 *
 * @file       		MK60_rtc
 * @company	   		成都逐飞科技有限公司
 * @author     		Go For It(1325536866)
 * @version    		v2.0
 * @Software 		IAR 7.7 or MDK 5.17
 * @Target core		MK60DN and MK60FX
 * @Taobao   		https://seekfree.taobao.com/
 * @date       		2017-09-19
 ********************************************************************************************************************/
 
 
#include "MK60_rtc.h"


//-------------------------------------------------------------------------------------------------------------------
//  @brief      RTC初始化
//  @return     void   
//  @since      v1.0
//  @note       使用RTC模块需要给最小系统的VBAT引脚供电才可以正常使用
//-------------------------------------------------------------------------------------------------------------------
void rtc_init(void)
{
    volatile uint32 delay;

    SIM->SCGC6 |= SIM_SCGC6_RTC_MASK;   //开启 RTC 时钟

    RTC->CR  = RTC_CR_SWR_MASK;         //复位 RTC 寄存器（除 SWR， RTC_WAR ， RTC_RAR ）
    RTC->CR  &= ~RTC_CR_SWR_MASK;       //清空复位标志位
    RTC->CR  = (0
               | RTC_CR_OSCE_MASK       //32.768 kHz 晶振 使能
               //| RTC_CR_SC2P_MASK     //加入 2p 电容
               //| RTC_CR_SC4P_MASK     //加入 4p 电容
               //| RTC_CR_SC8P_MASK     //加入 8p 电容
               | RTC_CR_SC16P_MASK      //加入 16p 电容
               | RTC_CR_CLKO_MASK       //RTC_CLKOUT 输出 32k 使能 (0表示输出，1表示禁止)
              );

    delay = 0x600000;
    while(delay--);                     //等待 32K 晶振稳定（起振时间需要看晶振手册）

    //设置时间补偿
    RTC->TCR = (0
               | RTC_TCR_CIR(0)         //补偿间隔(可以从1秒(0X0)到256(0xFF)的范围内),8bit
               | RTC_TCR_TCR(0)         //补偿值的范围从 32*1024Hz -127 的周期到 32*1024Hz +128 周期，即 TCR 范围为 (int8)-127 ~ (int8)128
              );

    RTC->SR &= RTC_SR_TCE_MASK;          //禁用RTC 计数器，便于后续设置寄存器  TSR 和 TPR

    //时间和闹钟设置
    RTC->TSR = 0;                        //当前时间
    RTC->TAR = 0;                        //闹钟时间

    //中断配置
    RTC->IER = (0
               //| RTC_IER_TAIE_MASK    //闹钟中断使能（0表示禁止，1表示使能）
               //| RTC_IER_TOIE_MASK    //溢出中断使能（0表示禁止，1表示使能）
               //| RTC_IER_TIIE_MASK    //无效时间中断使能（0表示禁止，1表示使能）
              );

    RTC->SR |= RTC_SR_TCE_MASK;          //使能RTC 计数器
}

//-------------------------------------------------------------------------------------------------------------------
//  @brief      设置当前时间
//  @param      seconds         需要设置的时间
//  @return     void   
//  @since      v1.0
//-------------------------------------------------------------------------------------------------------------------
void rtc_set_time(uint32 seconds)
{
    RTC->SR &= ~RTC_SR_TCE_MASK;         //禁用RTC 计数器，便于后续设置寄存器  TSR 和 TPR
    RTC->TSR = seconds;                  //当前时间
    RTC->SR |= RTC_SR_TCE_MASK;          //使能RTC 计数器
}

//-------------------------------------------------------------------------------------------------------------------
//  @brief      获取当前时间
//  @param      seconds         需要设置的时间
//  @return     void   
//  @since      v1.0
//-------------------------------------------------------------------------------------------------------------------
uint32 rtc_get_time(void)
{
    return RTC->TSR;
}

//-------------------------------------------------------------------------------------------------------------------
//  @brief      设置RTC闹钟时间，使能闹钟中断
//  @param      alarm    闹钟时间
//  @return     设置闹钟结果(0表示失败，1表示成功)  
//  @since      v1.0
//-------------------------------------------------------------------------------------------------------------------
uint8 rtc_set_alarm(uint32 alarm)
{
    if(alarm < RTC->TSR)                 //闹钟时间不能为过去时间
    {
        return 0;
    }

    RTC->SR &= ~RTC_SR_TCE_MASK;         //禁用RTC 计数器，便于后续设置寄存器  TSR 和 TPR

    RTC->TAR = alarm;                    //闹钟时间
    RTC->SR |= RTC_SR_TCE_MASK;          //使能RTC 计数器

    RTC->IER |= RTC_IER_TAIE_MASK;       //使能闹钟中断

    return 1;
}

//-------------------------------------------------------------------------------------------------------------------
//  @brief      关闭闹钟中断
//  @return     void
//  @since      v1.0
//-------------------------------------------------------------------------------------------------------------------
void rtc_close_alarm(void)
{
    RTC->IER &= ~RTC_IER_TAIE_MASK;      //禁止闹钟中断
}

//-------------------------------------------------------------------------------------------------------------------
//  @brief      RTC测试中断服务函数
//  @return     void
//  @since      v1.0
//-------------------------------------------------------------------------------------------------------------------
//void RTC_IRQHandler(void)
//{
//    uint32 sr = RTC->SR;
//
//    if(sr & RTC_SR_TIF_MASK) //无效设置
//    {
//        //清TIF、TOF位，禁用计数时写TSR寄存器就会清空此位
//        RTC->SR = (0
//                  //| RTC_SR_TCE_MASK    //计能使数(0为禁止，1为使能)
//                  );
//        RTC->TSR = 0;  //秒计数寄存器，写操作来清空TIF位
//
//        //下面由用户加入自己的代码
//        //printf("\nRTC无效设置");
//    }
//
//    if(sr & RTC_SR_TOF_MASK)  //溢出
//    {
//
//        //清TIF、TOF位，禁用计数时写TSR寄存器就会清空此位
//        RTC->SR = (0
//                  //| RTC_SR_TCE_MASK    //计能使数(0为禁止，1为使能)
//                  );
//        RTC->TSR = 0;  //秒计数寄存器，写操作来清空TIF位
//
//        //下面由用户加入自己的代码
//        //printf("\nRTC溢出");
//    }
//
//    if(sr & RTC_SR_TAF_MASK)  //报警
//    {
//        //写 TAR 来清空 SR_TAF
//        RTC->TAR = 0;
//
//        //下面由用户加入自己的代码
//        //printf("\nRTC报警");
//    }
//
//}
